package com.newhope.trade.getway.integration.filter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.newhope.trade.getway.integration.config.FilterConfig;
import com.newhope.trade.getway.integration.util.NewhopeHttpServletRequestWrapper;
import com.newhope.trade.getway.integration.vo.base.BaseResponse;
import com.tom.template.common.util.MD5Util;
import com.tom.template.api.enums.ResultCode;
import com.tom.template.api.bean.third.ThirdAppModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.Ordered;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

public class AuthFilter extends ZuulFilter {

	private final Logger logger = LoggerFactory.getLogger(AuthFilter.class);

	/**
	 * 访问白名单
	 */
	private  List<String> WHITE_LIST = Arrays.asList("/api/v2/template/openapi/test");


	@Override
	public boolean shouldFilter() {
		return true;
	}
	
	@Override
	public Object run() {
		RequestContext ctx = RequestContext.getCurrentContext();
		HttpServletRequest request = ctx.getRequest();
		String path = request.getPathInfo();

		//白名单不进行验签
		if(WHITE_LIST.contains(path)){
			return null;
		}

		try {
			String apiKey = null;
			Long timestamp = null;
			String sign = null;
			Map<String, Object> bizDataMap = new HashMap<>();
			String bizData = null;
			if (RequestMethod.GET.name().equals(request.getMethod()) || RequestMethod.DELETE.name().equals(request.getMethod())) {	//get,delete请求
				apiKey = request.getParameter("apikey");
				timestamp = Long.valueOf(request.getParameter("timestamp"));
				sign = request.getParameter("sign");
				// 构造bizData
				Enumeration<String> e = request.getParameterNames();
				while (e.hasMoreElements()) {
					String name = e.nextElement();
					if ("apikey".equals(name) || "timestamp".equals(name) || "sign".equals(name)) {
						continue;
					} else {
						bizDataMap.put(name, request.getParameter(name));
					}
				}
				bizData = JSON.toJSONString(bizDataMap);
			} else {	//其他请求contentType=application/json 流只能读一次注意
//
//           	BufferedReader reader = request.getReader();
//				JSONObject jsonObject = JSON.parseObject(reader.readLine(), Feature.OrderedField);

				NewhopeHttpServletRequestWrapper wrapper = new NewhopeHttpServletRequestWrapper(request);
				JSONObject jsonObject = JSON.parseObject(wrapper.getBodyString(),Feature.OrderedField);
				apiKey = jsonObject.getString("apikey");
				timestamp = jsonObject.getLong("timestamp");
				sign = jsonObject.getString("sign");
				bizData = jsonObject.getString("data");
				ctx.setRequest(wrapper);
			}
			
			logger.info("bizData是》》》》》》》》》》" + bizData);
			
			// 判断请求重放时间是否过期(1分钟)
			Long currentTimestamp = System.currentTimeMillis() / 1000;
			logger.info("currentTimestamp是》》》》》》》》》》" + currentTimestamp);
			logger.info("timestamp是》》》》》》》》》》" + timestamp);
			logger.info("currentTimestamp - timestamp是》》》》》》》》》》" +  (currentTimestamp - timestamp));
			if (currentTimestamp - timestamp > 120) {
				logger.error("timestamp过期");
				writeResponse(ctx, ResultCode.THIRD_EXPIRE);
				return null;
			}
			
			// 参数验签
			String text = new StringBuilder().append(apiKey)
					.append(timestamp).append(bizData)
					.toString();
			Object obj = null;
			if (obj != null && obj instanceof ThirdAppModel) {
				ThirdAppModel thirdApp = (ThirdAppModel) obj;
				String key = thirdApp.getSecretKey();
				String md5 = MD5Util.sign(text, key, "utf-8");
				if (!sign.equals(md5)) {
					logger.error("数据验签失败");
					writeResponse(ctx, ResultCode.THIRD_SIGN_FAIL);
					return null;
				}
			} else {
				logger.error("接口未授权");
				writeResponse(ctx, ResultCode.THIRD_API_UNAUTH);
				return null;
			}
		} catch (NullPointerException e) {
			logger.error("[ApiAuthInterceptor]参数错误", e);
		//	writeResponse(ctx, ResultCode.PARAM_ERROR);
			return null;
		} catch (Exception e) {
			logger.error("[ApiAuthInterceptor]系统错误", e);
			writeResponse(ctx, ResultCode.ERROR);
			return null;
		}
		logger.info("验签通过");
		return null;
	}
	@Override
	public String filterType() {
		return FilterConfig.FILTER_TYPE_PRE;
	}
	@Override
	public int filterOrder() {
		return Ordered.LOWEST_PRECEDENCE;
	}

	private void writeResponse(RequestContext ctx, ResultCode resultCode) {
		ctx.setSendZuulResponse(false);
		ctx.setResponseStatusCode(200);
		BaseResponse<Object> res = new BaseResponse<>();
		res.setCode(resultCode.name());
		res.setMsg(resultCode.getDesc());
		ctx.getResponse().setContentType("text/html;charset=UTF-8");
		ctx.setResponseBody(JSON.toJSONString(res));
	}
}
